package com.qf.filter;

import com.netflix.zuul.ZuulFilter;
import com.netflix.zuul.context.RequestContext;
import com.netflix.zuul.exception.ZuulException;
import com.qf.constans.SystemParameter;
import com.qf.feign.RedisService;
import com.qf.utils.Md5Util;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.netflix.zuul.filters.support.FilterConstants;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.util.Enumeration;
import java.util.Map;
import java.util.TreeMap;

/**
 * 自定义的用户签名校验
 * */

@Component
public class signFilter extends ZuulFilter {

    @Resource
    private RedisService redisService;

    @Override
    public String filterType() {
        return FilterConstants.PRE_TYPE;
    }

    @Override
    public int filterOrder() {
        return 10;
    }

    @Override
    public boolean shouldFilter() {
        return RequestContext.getCurrentContext().sendZuulResponse();
    }

    @Override
    public Object run() throws ZuulException {
        //校验签名  制定规则：将参数和自己的密钥按照一定的顺序加密后传输参数和sign，
        // 通过appkey获得用户id查询用户的密钥，和参数一起加密后比较值是否一样
        RequestContext currentContext = RequestContext.getCurrentContext();
        HttpServletRequest request = currentContext.getRequest();
        String sign = request.getParameter("sign"); //获取用户签名
        String appkey = request.getParameter("appkey");//获取用户id

        Enumeration<String> parameterNames = request.getParameterNames();   //获取全部参数名
        TreeMap<String,String> map = new TreeMap<>();   //创建存放全部参数（不包含sign）的有序集合，方便加密
        while (parameterNames.hasMoreElements()){
            String param = parameterNames.nextElement();
            if (param.equalsIgnoreCase("sign")){
                continue;
            }
            map.put(param,request.getParameter(param));
        }

        Map<Object, Object> appinfoMap = redisService.hgetAll(SystemParameter.USERSESSION + ":" + appkey);
        String appsecret = (String) appinfoMap.get("appsecret");
        String signature = Md5Util.md5Signature(map, appsecret);   //获得用户签名
        System.out.println("用户签名为："+signature);

        if (!signature.equalsIgnoreCase(sign)){
            currentContext.setSendZuulResponse(false);
            currentContext.setResponseBody("用户签名不正确！！");
            currentContext.getResponse().setContentType("text/html;charset=utf-8");
        }else {
            //在redis中放入signature用来判断是否是重复请求
            redisService.set(signature,"asdf",60000L);
        }

        return null;
    }
}
